home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / kgdb-4.5 / ds3100.md / gdb / core.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-30  |  14.1 KB  |  540 lines

  1. /* Work with core dump and executable files, for GDB.
  2.    Copyright 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
  3.  
  4. This file is part of GDB.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "defs.h"
  21. #include <errno.h>
  22. #include <signal.h>
  23. #include <fcntl.h>
  24. #include "frame.h"  /* required by inferior.h */
  25. #include "inferior.h"
  26. #include "symtab.h"
  27. #include "command.h"
  28. #include "bfd.h"
  29. #include "target.h"
  30. #include "gdbcore.h"
  31. #include "./../bfd/vm-core.h"
  32. #include <kernel/dbg.h>
  33. #include <kernel/machTypes.h>
  34. #include <kernel/procTypes.h>
  35.  
  36. CORE_ADDR data_start;
  37. CORE_ADDR data_end;
  38. CORE_ADDR stack_start;
  39. CORE_ADDR stack_end;
  40. CORE_ADDR text_start;
  41. CORE_ADDR text_end;
  42. CORE_ADDR exec_data_start;
  43. CORE_ADDR exec_data_end;
  44.  
  45. #ifdef SOLIB_ADD
  46. static int 
  47. solib_add_stub PARAMS ((char *));
  48. #endif
  49.  
  50. static void
  51. core_close PARAMS ((int));
  52.  
  53. static void
  54. core_open PARAMS ((char *, int));
  55.  
  56. static void
  57. core_detach PARAMS ((char *, int));
  58.  
  59. static void
  60. get_core_registers PARAMS ((int));
  61.  
  62. static void
  63. core_files_info PARAMS ((struct target_ops *));
  64.  
  65. extern int sys_nerr;
  66. extern char *sys_errlist[];
  67. extern char *sys_siglist[];
  68. extern StopInfo remoteStopInfo;
  69. extern int lastPid;
  70.  
  71. extern char registers[];
  72.  
  73. /* Hook for `exec_file_command' command to call.  */
  74.  
  75. void (*exec_file_display_hook) PARAMS ((char *)) = NULL;
  76.  
  77. /* Binary file diddling handle for the core file.  */
  78.  
  79. bfd *core_bfd = NULL;
  80.  
  81. /* Forward decl */
  82. extern struct target_ops core_ops;
  83.  
  84.  
  85. /* Discard all vestiges of any previous core file
  86.    and mark data and stack spaces as empty.  */
  87.  
  88. /* ARGSUSED */
  89. static void
  90. core_close (quitting)
  91.      int quitting;
  92. {
  93.   if (core_bfd) {
  94.     free (bfd_get_filename (core_bfd));
  95.     bfd_close (core_bfd);
  96.     core_bfd = NULL;
  97. #ifdef CLEAR_SOLIB
  98.     CLEAR_SOLIB ();
  99. #endif
  100.     if (core_ops.to_sections) {
  101.       free ((PTR)core_ops.to_sections);
  102.       core_ops.to_sections = NULL;
  103.       core_ops.to_sections_end = NULL;
  104.     }
  105.   }
  106. }
  107.  
  108. #ifdef SOLIB_ADD
  109. /* Stub function for catch_errors around shared library hacking. */
  110.  
  111. static int 
  112. solib_add_stub (from_tty)
  113.      char *from_tty;
  114. {
  115.     SOLIB_ADD (NULL, (int)from_tty, &core_ops);
  116.     return 0;
  117. }
  118. #endif /* SOLIB_ADD */
  119.  
  120. /* This routine opens and sets up the core file bfd */
  121.  
  122. static void
  123. core_open (filename, from_tty)
  124.      char *filename;
  125.      int from_tty;
  126. {
  127.   const char *p;
  128.   int siggy;
  129.   struct cleanup *old_chain;
  130.   char *temp;
  131.   bfd *temp_bfd;
  132.   int ontop;
  133.   int scratch_chan;
  134.  
  135.   target_preopen (from_tty);
  136.   if (!filename)
  137.     {
  138.       error (core_bfd? 
  139.        "No core file specified.  (Use `detach' to stop debugging a core file.)"
  140.      : "No core file specified.");
  141.     }
  142.  
  143.   filename = tilde_expand (filename);
  144.   if (filename[0] != '/') {
  145.     temp = concat (current_directory, "/", filename, NULL);
  146.     free (filename);
  147.     filename = temp;
  148.   }
  149.  
  150.   old_chain = make_cleanup (free, filename);
  151.  
  152.   scratch_chan = open (filename, write_files? O_RDWR: O_RDONLY, 0);
  153.   if (scratch_chan < 0)
  154.     perror_with_name (filename);
  155.  
  156.   temp_bfd = bfd_fdopenr (filename, NULL, scratch_chan);
  157.   if (temp_bfd == NULL)
  158.     {
  159.       perror_with_name (filename);
  160.     }
  161.  
  162.   if (!bfd_check_format (temp_bfd, bfd_core))
  163.     {
  164.       /* Do it after the err msg */
  165.       make_cleanup (bfd_close, temp_bfd);
  166.       error ("\"%s\" is not a core dump: %s", filename, bfd_errmsg(bfd_error));
  167.     }
  168.  
  169.   /* Looks semi-reasonable.  Toss the old core file and work on the new.  */
  170.  
  171.   discard_cleanups (old_chain);        /* Don't free filename any more */
  172.   unpush_target (&core_ops);
  173.   core_bfd = temp_bfd;
  174.   old_chain = make_cleanup (core_close, core_bfd);
  175.  
  176.   validate_files ();
  177.  
  178.   /* Find the data section */
  179.   if (build_section_table (core_bfd, &core_ops.to_sections,
  180.                &core_ops.to_sections_end))
  181.     error ("Can't find sections in `%s': %s", bfd_get_filename(core_bfd),
  182.        bfd_errmsg (bfd_error));
  183.  
  184.   ontop = !push_target (&core_ops);
  185.   discard_cleanups (old_chain);
  186.  
  187.   p = bfd_core_file_failing_command (core_bfd);
  188.   if (p)
  189.     printf ("Core was generated by `%s'.\n", p);
  190.  
  191.   siggy = bfd_core_file_failing_signal (core_bfd);
  192.   if (siggy > 0)
  193.     printf ("Program terminated with signal %d, %s.\n", siggy,
  194.         siggy < NSIG ? sys_siglist[siggy] : "(undocumented)");
  195.  
  196.   if (ontop) {
  197.     /* Fetch all registers from core file */
  198.     target_fetch_registers (-1);
  199.  
  200.     /* Add symbols and section mappings for any shared libraries */
  201. #ifdef SOLIB_ADD
  202.     (void) catch_errors (solib_add_stub, (char *)from_tty, (char *)0);
  203. #endif
  204.     
  205.     bcopy(bfd_get_vm_core_stopinfo(core_bfd), &remoteStopInfo, sizeof remoteStopInfo);
  206.     supply_register(FP_REGNUM, &remoteStopInfo.regs.regs[29]);
  207.     supply_register(SP_REGNUM, &remoteStopInfo.regs.regs[29]);
  208.     supply_register(PC_REGNUM, &remoteStopInfo.regs.pc);
  209.     /* Now, set up the frame cache, and print the top of stack */
  210.     set_current_frame (create_new_frame (read_register (FP_REGNUM),
  211.                      read_pc ()));
  212.     select_frame (get_current_frame (), 0);
  213.     print_stack_frame (selected_frame, selected_frame_level, 1);
  214.   } else {
  215.     printf (
  216. "Warning: you won't be able to access this core file until you terminate\n\
  217. your %s; do ``info files''\n", current_target->to_longname);
  218.   }
  219. }
  220.  
  221. int
  222. core_attach(pid)
  223.     int    pid;
  224. {
  225.   int    status;
  226.   struct expression *expr;
  227.   register struct cleanup *old_chain;
  228.   register value val;
  229.   int    machRegStateAddr;
  230.   Proc_ControlBlock    *procPtr;
  231.   Mach_RegState machRegState;
  232.   char    exp[128];
  233.   
  234.   if (pid != lastPid) {
  235.     /*
  236.      * Switching to a new process. 
  237.      */
  238.     if (pid == -1) {
  239.       /*
  240.        * Process -1 is the trap process. Whose stop info is 
  241.        * in the beginning of the corefile.
  242.        */
  243.       bcopy(bfd_get_vm_core_stopinfo(core_bfd), &remoteStopInfo, sizeof remoteStopInfo);
  244.       supply_register(FP_REGNUM, &remoteStopInfo.regs.regs[29]);
  245.       supply_register(SP_REGNUM, &remoteStopInfo.regs.regs[29]);
  246.       supply_register(PC_REGNUM, &remoteStopInfo.regs.pc);
  247.       /* Now, set up the frame cache, and print the top of stack */
  248.       set_current_frame (create_new_frame (read_register (FP_REGNUM),
  249.                        read_pc ()));
  250.       select_frame (get_current_frame (), 0);
  251.       print_stack_frame (selected_frame, selected_frame_level, 1);
  252.       lastPid = pid;
  253.       return 1;
  254.     }
  255.     /*
  256.      * Lookup the switch regs of the specified process.
  257.      * They are in proc_PCBTable[pidSlot]->machStatePtr->switchRegs.
  258.      */
  259.     sprintf(exp,"proc_PCBTable[%d]", pid & 0xff);
  260.     expr = parse_expression (exp);
  261.     old_chain = make_cleanup (free_current_contents, &expr);
  262.     
  263.     val = evaluate_expression (expr);
  264.     do_cleanups (old_chain);
  265.     if ((value_as_long(val) == NIL) || (value_as_long(val) == 0)) {
  266.       error("Pid 0x%x does not have a control block\n", pid);
  267.     }
  268.     sprintf(exp,"&(proc_PCBTable[%d]->machStatePtr->switchRegState)", pid & 0xff);
  269.     expr = parse_expression (exp);
  270.     old_chain = make_cleanup (free_current_contents, &expr);
  271.     val = evaluate_expression (expr);
  272.     do_cleanups (old_chain);
  273.     machRegStateAddr = value_as_long(val);
  274.     machRegState.pc = 320;
  275.     if (target_xfer_memory(machRegStateAddr, &machRegState, 
  276.               sizeof(Mach_RegState), 0) != 0) {
  277.       error("Can't read  regs from address 0x%x\n", machRegStateAddr);
  278.     }
  279.     remoteStopInfo.regs = machRegState;
  280.     /*
  281.      * The PC that is stored for a switch registers from on the
  282.      * sun4 is bogus.  We set the PC to be inside Mach_ContextSwitch.
  283.      */
  284.     strcpy(exp,"&Mach_ContextSwitch");
  285.     expr = parse_expression (exp);
  286.     old_chain = make_cleanup (free_current_contents, &expr);
  287.     val = evaluate_expression (expr);
  288.     do_cleanups (old_chain);
  289.     remoteStopInfo.regs.pc = value_as_long(val)+16;
  290.     remoteStopInfo.regs.regs[29] = remoteStopInfo.regs.regs[29];
  291. /*    supply_register(FP_REGNUM, &remoteStopInfo.regs.regs[29]);*/
  292.     supply_register(SP_REGNUM, &remoteStopInfo.regs.regs[29]);
  293.     supply_register(PC_REGNUM, &remoteStopInfo.regs.pc);
  294.     /* Now, set up the frame cache, and print the top of stack */
  295.     set_current_frame (create_new_frame (read_register (FP_REGNUM),
  296.                      read_pc ()));
  297.     select_frame (get_current_frame (), 0);
  298.     print_stack_frame (selected_frame, selected_frame_level, 1);
  299.     lastPid = pid;
  300.   }
  301.   return 1;
  302. }
  303.  
  304. static void
  305. core_detach (args, from_tty)
  306.      char *args;
  307.      int from_tty;
  308. {
  309.   if (args)
  310.     error ("Too many arguments");
  311.   unpush_target (&core_ops);
  312.   if (from_tty)
  313.     printf ("No core file now.\n");
  314. }
  315.  
  316. /* Backward compatability with old way of specifying core files.  */
  317.  
  318. void
  319. core_file_command (filename, from_tty)
  320.      char *filename;
  321.      int from_tty;
  322. {
  323.   dont_repeat ();            /* Either way, seems bogus. */
  324.   if (!filename)
  325.     core_detach (filename, from_tty);
  326.   else
  327.     core_open (filename, from_tty);
  328. }
  329.  
  330.  
  331. /* Call this to specify the hook for exec_file_command to call back.
  332.    This is called from the x-window display code.  */
  333.  
  334. void
  335. specify_exec_file_hook (hook)
  336.      void (*hook) PARAMS ((char *));
  337. {
  338.   exec_file_display_hook = hook;
  339. }
  340.  
  341. /* The exec file must be closed before running an inferior.
  342.    If it is needed again after the inferior dies, it must
  343.    be reopened.  */
  344.  
  345. void
  346. close_exec_file ()
  347. {
  348. #ifdef FIXME
  349.   if (exec_bfd)
  350.     bfd_tempclose (exec_bfd);
  351. #endif
  352. }
  353.  
  354. void
  355. reopen_exec_file ()
  356. {
  357. #ifdef FIXME
  358.   if (exec_bfd)
  359.     bfd_reopen (exec_bfd);
  360. #endif
  361. }
  362.  
  363. /* If we have both a core file and an exec file,
  364.    print a warning if they don't go together.  */
  365.  
  366. void
  367. validate_files ()
  368. {
  369.   if (exec_bfd && core_bfd)
  370.     {
  371.       if (!core_file_matches_executable_p (core_bfd, exec_bfd))
  372.     printf ("Warning: core file may not match specified executable file.\n");
  373.       else if (bfd_get_mtime(exec_bfd) > bfd_get_mtime(core_bfd))
  374.     printf ("Warning: exec file is newer than core file.\n");
  375.     }
  376. }
  377.  
  378. /* Return the name of the executable file as a string.
  379.    ERR nonzero means get error if there is none specified;
  380.    otherwise return 0 in that case.  */
  381.  
  382. char *
  383. get_exec_file (err)
  384.      int err;
  385. {
  386.   if (exec_bfd) return bfd_get_filename(exec_bfd);
  387.   if (!err)     return NULL;
  388.  
  389.   error ("No executable file specified.\n\
  390. Use the \"file\" or \"exec-file\" command.");
  391.   return NULL;
  392. }
  393.  
  394. static void
  395. core_files_info (t)
  396.   struct target_ops *t;
  397. {
  398.   print_section_info (t, core_bfd);
  399. }
  400.  
  401. /* Report a memory error with error().  */
  402.  
  403. void
  404. memory_error (status, memaddr)
  405.      int status;
  406.      CORE_ADDR memaddr;
  407. {
  408.  
  409.   if (status == EIO)
  410.     {
  411.       /* Actually, address between memaddr and memaddr + len
  412.      was out of bounds. */
  413.       error ("Cannot access memory at address %s.", local_hex_string(memaddr));
  414.     }
  415.   else
  416.     {
  417.       if (status >= sys_nerr || status < 0)
  418.     error ("Error accessing memory address %s: unknown error (%d).",
  419.            local_hex_string(memaddr), status);
  420.       else
  421.     error ("Error accessing memory address %s: %s.",
  422.            local_hex_string(memaddr), sys_errlist[status]);
  423.     }
  424. }
  425.  
  426. /* Same as target_read_memory, but report an error if can't read.  */
  427. void
  428. read_memory (memaddr, myaddr, len)
  429.      CORE_ADDR memaddr;
  430.      char *myaddr;
  431.      int len;
  432. {
  433.   int status;
  434.   status = target_read_memory (memaddr, myaddr, len);
  435.   if (status != 0)
  436.     memory_error (status, memaddr);
  437. }
  438.  
  439. /* Same as target_write_memory, but report an error if can't write.  */
  440. void
  441. write_memory (memaddr, myaddr, len)
  442.      CORE_ADDR memaddr;
  443.      char *myaddr;
  444.      int len;
  445. {
  446.   int status;
  447.  
  448.   status = target_write_memory (memaddr, myaddr, len);
  449.   if (status != 0)
  450.     memory_error (status, memaddr);
  451. }
  452.  
  453. /* Read an integer from debugged memory, given address and number of bytes.  */
  454.  
  455. long
  456. read_memory_integer (memaddr, len)
  457.      CORE_ADDR memaddr;
  458.      int len;
  459. {
  460.   char cbuf;
  461.   short sbuf;
  462.   int ibuf;
  463.   long lbuf;
  464.  
  465.   if (len == sizeof (char))
  466.     {
  467.       read_memory (memaddr, &cbuf, len);
  468.       return cbuf;
  469.     }
  470.   if (len == sizeof (short))
  471.     {
  472.       read_memory (memaddr, (char *)&sbuf, len);
  473.       SWAP_TARGET_AND_HOST (&sbuf, sizeof (short));
  474.       return sbuf;
  475.     }
  476.   if (len == sizeof (int))
  477.     {
  478.       read_memory (memaddr, (char *)&ibuf, len);
  479.       SWAP_TARGET_AND_HOST (&ibuf, sizeof (int));
  480.       return ibuf;
  481.     }
  482.   if (len == sizeof (lbuf))
  483.     {
  484.       read_memory (memaddr, (char *)&lbuf, len);
  485.       SWAP_TARGET_AND_HOST (&lbuf, sizeof (lbuf));
  486.       return lbuf;
  487.     }
  488.   error ("Cannot handle integers of %d bytes.", len);
  489.   return -1;    /* for lint */
  490. }
  491.  
  492. /* Get the registers out of a core file.  This is the machine-
  493.    independent part.  Fetch_core_registers is the machine-dependent
  494.    part, typically implemented in the xm-file for each architecture.  */
  495.  
  496. /* We just get all the registers, so we don't use regno.  */
  497. /* ARGSUSED */
  498. static void
  499. get_core_registers (regno)
  500.      int regno;
  501. {
  502.   sec_ptr reg_sec;
  503.   unsigned size;
  504.   char *the_regs;
  505.  
  506.   the_regs = (char *) bfd_get_vm_core_regs (core_bfd);
  507.   fetch_core_registers (the_regs, size, 0, NULL);
  508.   
  509.   registers_fetched();
  510. }
  511.  
  512. struct target_ops core_ops = {
  513.     "core", "Local core dump file",
  514.     "Use a core file as a target.  Specify the filename of the core file.",
  515.     core_open, core_close,
  516.     core_attach, core_detach, 0, 0, /* resume, wait */
  517.     get_core_registers, 
  518.     0, 0, 0, 0, /* store_regs, prepare_to_store, conv_to, conv_from */
  519.     xfer_memory, core_files_info,
  520.     0, 0, /* core_insert_breakpoint, core_remove_breakpoint, */
  521.     0, 0, 0, 0, 0, /* terminal stuff */
  522.     0, 0, 0, /* kill, load, lookup sym */
  523.     child_create_inferior, 0, /* mourn_inferior */
  524.     core_stratum, 0, /* next */
  525.     0, 1, 1, 1, 0,    /* all mem, mem, stack, regs, exec */
  526.     0, 0,            /* section pointers */
  527.     OPS_MAGIC,        /* Always the last thing */
  528. };
  529.  
  530. void
  531. _initialize_core()
  532. {
  533.  
  534.   add_com ("core-file", class_files, core_file_command,
  535.        "Use FILE as core dump for examining memory and registers.\n\
  536. No arg means have no core file.  This command has been superseded by the\n\
  537. `target core' and `detach' commands.");
  538.   add_target (&core_ops);
  539. }
  540.